//This file is part of Image Mining Framework.
//
//    Image Mining Framework is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    Image Mining Framework is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with Image Mining Framework.  If not, see <http://www.gnu.org/licenses/>.

import ij.*;
import ij.WindowManager;
import java.lang.Math.*;
import ij.process.ImageProcessor;
import java.awt.image.*;
import java.io.*;
import java.awt.Color.*;
import ij.gui.GenericDialog;
import ij.plugin.filter.PlugInFilter;
import ij.text.TextPanel;
import java.awt.Rectangle;
import ij.text.TextWindow;
/**
 * Class featureVector_ is an ImageJ plugin that implements the
 * selective sliding window algorithm proposed by D.K. Iakovidis in IST 2008 and BIBE 2008.
 * @author Michael Dompekidis and Dimitris K. Iakovids
 **/
public class featureVector_ implements PlugInFilter
{
  private int       boxWidth,
                    boxHeight,
                    boxStepX,boxStepY;
  private boolean localSave;
  TextWindow textLog;
 
  String finalString = "Feature Vector"+"\n"+"\n";
  public BufferedImage betaImg;
  public BufferedImage IMFImage;
 
  public BufferedWriter bufferedWriter = null;
  public  BufferedWriter out;
   
  public int setup(String arg, ImagePlus imp)
  {
        imp = WindowManager.getCurrentImage();
        return DOES_8G;
  }

  public void run(ImageProcessor ip)
  {
        // Default values
        boxWidth    = 24;
        boxHeight   = 24;
        boxStepX    = 1;
        boxStepY    = 1;
        localSave   = true;
        ImagePlus imp = WindowManager.getCurrentImage();
        //getting the area of interest that the user might have choosen
        Rectangle areaOfInterest = imp.getProcessor().getRoi();
        //if(areaOfInterest.width!=boxWidth&&areaOfInterest.width!=0)boxWidth=areaOfInterest.width;
        //if(areaOfInterest.height!=boxHeight&&areaOfInterest.height!=0)boxHeight=areaOfInterest.height;

        // Creates a new window on ImageJ where text, or GUI elements are added.
        GenericDialog gd = new GenericDialog("Feature Vector sampler");
        gd.addMessage("Sampling box preferences: ");
        gd.addNumericField("Width of the Box", boxWidth,1);
        gd.addNumericField("Height of the Box", boxHeight,1);
        gd.addNumericField("Box pacing on X-axis", boxStepX,1);
        gd.addNumericField("Box pacing on Y-axis", boxStepY,1);

        gd.addCheckbox("Save featureVectors locally", localSave);
        gd.showDialog();
        if(gd.wasCanceled())
        {
            IJ.error("Plugin canceled");
            return;
        }

        // Get GUI values
        boxWidth = (int)gd.getNextNumber();
        boxHeight = (int)gd.getNextNumber();
        boxStepX = (int)gd.getNextNumber();
        boxStepY = (int)gd.getNextNumber();
        if(gd.invalidNumber())
        {
            IJ.error("Invalid field");
            return;
        }
        //Checkbox value
        localSave = gd.getNextBoolean();
      
       // FileInfo fi = imp.getOriginalFileInfo();
        imp.updateAndDraw();

        featureExtractor featureUtil = new featureExtractor();
        //Start sliding window with inputs from dialog window.
        //Receives a textPanel with all the values.
        TextPanel vectorLog = featureUtil.slidingWindow(imp.getProcessor(),boxWidth,boxHeight,boxStepX,boxStepY,areaOfInterest,"log");


         textLog = new TextWindow("Log","",400,250);

          textLog.append(vectorLog.getText());
           if(localSave==true)
           {
               saveFeatures(vectorLog.getText());

           }
           return;
    }


     //exports the vectors to a file, this is better than buffered writer because temp values are already in
    // imageJ buffer, so we don't use more memory. In case of Memory Heap error, increase the max amount of memory used by ImageJ. 
    public void saveFeatures(String finalText)
    {
      
         IJ.saveString(finalText, "C:/SDK/Vector.txt");
         
    }
    
    /**
     * Obsolete, we can take double Arrays straight from the ArrayList. By reference.
     * Converts one array from the arrayList into an array of doubles. This ensures we retrieve only the desired subImage without having 2 arrays in
     * memory all the time.
     * @param arr the source array
     * @param length size of the source array
     * @param index obsolete now, we use 0 position.
     * @return
     */
    public Double[] makeDouble(int[] arr,int length,int index)
    {
        Double[] temp = new Double[length];
        System.arraycopy(arr, 0, temp, 0, length);

        return temp;
    }

  
    
    int readabilityCounter = 0;
    /**
     * Performs serialization of the results, appends new feature vectors in rows
     * for better readability when exported to file. Creates a gap between featureVectors.
     * Changes row every 5 entries.
     * Obsolete because of huge delay while processing the sliding window values. probably the Integer.toString() is too slow?
     * @param input The String to be appended
     * @param changeLine whether or not we reached the end of a series of rows.
     */
    public void serializer(String input,boolean changeLine)
    {
        if(changeLine==true){finalString = finalString+"\n"+"\n";}
        else
        {
            String tempStr = input;

            if(readabilityCounter<6)finalString =  finalString+tempStr+", ";
            else
            {
                finalString = finalString+tempStr+", "+"\n";
                readabilityCounter = 0;
            }
            readabilityCounter++;
        }
    }


   //Obsolete, we use IJ.saveString(String, path) now. Kept in case of non-ImageJ testing.
    private void writeOutput(String source)
    {
        try
        {
           out = new BufferedWriter(new FileWriter("C:/SDK/Vector.txt",true));

            //String someText = "aString\nthis is a\nttest";
            //someText.replaceAll("\n", System.getProperty("line.separator"));

            out.write(source);
            out.newLine();
            out.flush();
            out.close();
        }
        catch (IOException e)
        {
            IJ.log("Exception "+e);
        }
    }

    /**
     * Reads the file from the system.
     * @return a String with all the values separated by comma.
     */
    private String readLog()
    {
        String filename = "C:/SDK/Vector.txt";

          String records = new String();
          try
          {

            BufferedReader reader = new BufferedReader(new FileReader(filename));
            String line;
            while ((line = reader.readLine()) != null)
            {
              records = records+line;
            }
            reader.close();
            return records;
          }
          catch (Exception e)
          {
            System.err.format("Exception occurred trying to read '%s'.", filename);
            e.printStackTrace();
            return null;
          }

    }

 
    
}


